import datetime
import math
import re
from collections import OrderedDict
from django.utils.safestring import mark_safe
from django.db.models import F, Sum, Q
from django.conf import settings
from rest_framework.validators import UniqueTogetherValidator
from .models import GoodsImage, Goods, ReceiverPlace, CartItem, SupplyOrder, WomaiOrder, YF, AreaWareHouse, OrderIncome, \
    ReceiptDetails, Inventory, VaildArea, Logistics, Collect, WomaiChildOrder, IndexPre, Company, StartTime, Category, \
    TransferRecord, Banner, PostCompany, PostRecord, GoodsPrice, GoodsAttributeValue, GoodsAttribute, RefundRecord, \
    GGCardOrder
from .womai_api import WoMaiApi
from core.wchat.WXInstance import KLBWxPay as wx_pay
from core.tools.models import BankCode
from django.contrib.auth import get_user_model
from core.wchat.models import RefundRecord
from core.tools.func_utils import funcUtils
from core.tl.models import TLPayRecord, TLRefundRecord
from .utils import re_goods_detail_wm
from apps.czb.models import Orders as CzbOrder
from core.yl.client import YLClient
from core.yl.models import YLPayRecord, YLRefundRecord

orderModel = (("czb", "车主邦加油"),)
mai_api = WoMaiApi()
UserModel = get_user_model()

from rest_framework import serializers
from .models import RefundRecord


class RefundRecordSerializers(serializers.ModelSerializer):
    refund_fee = serializers.SerializerMethodField(read_only=True, label="退款金额")

    def get_refund_fee(self, instance):
        return int(instance.refund_fee) / 100.0

    class Meta:
        model = RefundRecord
        fields = ("refund_fee",)


# ------商品信息分割---------
# 商品基础信息
class BaseGoodsSerializers(serializers.ModelSerializer):
    goodsname = serializers.CharField(read_only=True, label="商品名称", help_text="商品名称")
    will_sales = serializers.SerializerMethodField(label="预售", help_text="预售", read_only=True)
    goods_images_index = serializers.SerializerMethodField(label="主图", help_text="主图", read_only=True)

    def get_goods_images_index(self, obj):
        index_image = obj.goods_images.filter(type=4).first()
        return index_image.path

    def get_will_sales(self, obj):
        now_time = datetime.datetime.now()
        if obj.active_start_time and obj.active_start_time.start_time > now_time:
            return False
        else:
            return True


# 商品价格base
class BaseAttrGoodsPriceSerializers(serializers.ModelSerializer):
    price = serializers.SerializerMethodField(label="当前购买价", help_text="当前购买价")
    sales_price = serializers.SerializerMethodField(label="销售价格", help_text="销售价格")
    sales_price_isvip = serializers.SerializerMethodField(label="会员价", read_only=True, help_text="会员价")

    # 会员价
    def get_sales_price_isvip(self, obj):
        price = obj.get_vip_price()
        return price / 100.0

    # 通过计算获取的购买价格
    def get_price(self, obj):
        user = self.context["request"].user
        price, order_type = obj.get_buy_price_attr(user)
        return price / 100.0

    # 销售价格
    def get_sales_price(self, obj):
        return obj.sales_price / 100.0

    class Meta:
        model = GoodsPrice
        fields = ("price", "sales_price", "sales_price_isvip")


# 基础价格 会员价，销售价
class BaseGoodsPriceSerializers(serializers.ModelSerializer):
    sales_price_isvip = serializers.SerializerMethodField(label="会员价", read_only=True, help_text="会员价")
    sales_price = serializers.SerializerMethodField(label="销售价格", help_text="销售价格", read_only=True)

    # 会员价
    def get_sales_price_isvip(self, obj):
        price = obj.get_vip_price()
        return price / 100.0

    # 销售价格
    def get_sales_price(self, obj):
        return obj.sales_price / 100.0


# 当前购买人价格
class GoodsBuyPriceSerializers(serializers.ModelSerializer):
    # 通过计算获取的购买价格
    price = serializers.SerializerMethodField(label="当前购买价", help_text="当前购买价")

    def get_price(self, obj):
        user = self.context["request"].user
        price, order_type = obj.get_buy_price(user)
        return price / 100.0


# ------商品信息分割---------

# banner
class BannerSerializers(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = ("banner", "url", "bg_color")


# 产品类型
class CategorySerializers(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = "__all__"


# 抢购时间
class ActiveTimeSerializers(serializers.ModelSerializer):
    time = serializers.SerializerMethodField()
    start_status = serializers.SerializerMethodField()
    start_time = serializers.DateTimeField(format=settings.API_DATETIME_FORMAT)

    def get_time(self, obj):
        now_time = datetime.date.today()
        start_time = obj.start_time.strftime("%Y-%m-%d")
        start_time = datetime.date(*(int(i) for i in start_time.split("-")))
        if start_time == now_time:
            return "%s:00" % obj.start_time.hour
        elif start_time > now_time:
            if (start_time - now_time).days > 1:
                return str(obj.start_time)[5:16].replace("-", "月")
            return "明日 %s:00" % obj.start_time.hour
        else:
            return "昨日 %s:00" % obj.start_time.hour

    def get_start_status(self, obj):
        now_time = datetime.datetime.now()
        if obj.start_time > now_time:
            return 0
        else:
            return 1

    class Meta:
        model = StartTime
        # fields = ("id", "time", "start_status")
        fields = "__all__"


# 公司信息
class CompanySerializers(serializers.ModelSerializer):
    class Meta:
        model = Company
        fields = "__all__"


# 首页专区
class IndexPreSerializers(serializers.ModelSerializer):
    class Meta:
        model = IndexPre
        exclude = ("order",)


# 收货地址
class ReceiverPlaceSerializers(serializers.ModelSerializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    update_time = serializers.DateTimeField(format=settings.API_DATETIME_FORMAT, read_only=True)

    # default = serializers.BooleanField(default=True, label="是否是默认地址")

    class Meta:
        model = ReceiverPlace
        exclude = ("postcode", "receiver_phone", "status")

    def create(self, validated_data):
        validated_data["default"] = True
        user = validated_data["user"]
        ReceiverPlace.objects.update_default(user)
        return super(ReceiverPlaceSerializers, self).create(validated_data)

    def update(self, instance, validated_data):
        validated_data["default"] = True
        user = validated_data["user"]
        ReceiverPlace.objects.update_default(user)
        return super(ReceiverPlaceSerializers, self).update(instance, validated_data)


class ReceiverPlaceDeleteSerializers(serializers.ModelSerializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    status = serializers.BooleanField(write_only=True, label="删除默认是False", help_text="删除默认是False")

    class Meta:
        model = ReceiverPlace
        fields = ("status", "user",)

    def validate(self, attrs):
        try:
            status = attrs.get("status")
            if status is False:
                return attrs
            else:
                raise serializers.ValidationError("删除收货地址请传{status:false}")
        except KeyError as e:
            raise serializers.ValidationError("删除收货地址请传status参数")

    def update(self, instance, validated_data):
        user = validated_data["user"]
        if instance.status:
            ReceiverPlace.objects.update_default_by_update_time(user)
        return super(ReceiverPlaceDeleteSerializers, self).update(instance, validated_data)


# 发票
class ReceiptDetailsSerializers(serializers.ModelSerializer):
    """
    发票
    """

    class Meta:
        model = ReceiptDetails
        fields = "__all__"


# 商品图片
class GoodsImageSerializers(serializers.ModelSerializer):
    class Meta:
        model = GoodsImage
        fields = "__all__"


# 订单商品
class OrderGoodsSerializers(serializers.ModelSerializer):
    goods_images_index = serializers.SerializerMethodField(label="主图", help_text="主图")
    price = serializers.SerializerMethodField(label="当前购买价", help_text="当前购买价")
    sales_price_isvip = serializers.SerializerMethodField(label="会员价", read_only=True, help_text="会员价")
    weight = serializers.CharField(read_only=True, label="重量", help_text="重量")
    goodsname = serializers.CharField(read_only=True, label="商品名称", help_text="商品名称")
    unit = serializers.CharField(read_only=True, label="单位", help_text="单位")
    will_sales = serializers.SerializerMethodField(label="预售", help_text="预售")
    sales_price = serializers.SerializerMethodField(label="销售价格", help_text="销售价格")
    post_fee = serializers.SerializerMethodField(label="运费", help_text="运费")

    # 会员价
    def get_sales_price_isvip(self, obj):
        price = obj.get_vip_price()
        return price / 100.0

    # 通过计算获取的购买价格
    def get_price(self, obj):
        user = self.context["request"].user
        price, order_type = obj.get_buy_price(user)
        return price / 100.0

    # 销售价格
    def get_sales_price(self, obj):
        return obj.sales_price / 100.0

    def get_post_fee(self, instance):
        if instance.company.sign == "womaiwang":
            if instance.goodstype.goods_type == 142:
                type_142_weight = int(instance.weight)
                type_143_weight = 0
            else:
                type_142_weight = 0
                type_143_weight = int(instance.weight)
            user = self.context["request"].user
            if user.is_authenticated:
                user_receiver = user.user_receiver_info.filter(default=True)
                if user_receiver.exists():
                    user_receiver = user_receiver.first()
                    post_fee = YF.objects.get_price(user_receiver.province, type_142_weight, type_143_weight)  # 应收运费
                    return post_fee / 100.0
                else:
                    return instance.post_fee / 100.0
            else:
                return instance.post_fee / 100.0
        else:
            return instance.post_fee / 100.0

    def get_will_sales(self, obj):
        now_time = datetime.datetime.now()
        if obj.active_start_time and obj.active_start_time.start_time > now_time:
            return False
        else:
            return True

    def get_goods_images_index(self, obj):
        index_image = obj.goods_images.filter(type=4).first()
        return index_image.path

    def get_goodsname(self, instance):
        if "【自营】" in instance.goodsname:
            return instance.goodsname.replace("【自营】", "【我买网自营】")
        else:
            return instance.goodsname

    class Meta:
        model = Goods
        fields = ("id", "goods_images_index", "weight", "unit", "goodsname", "price", "sales_price_isvip",
                  "will_sales", "sales_price", "is_vip_bag", "post_fee")


# 商品列表
class GoodsSerializers(OrderGoodsSerializers):
    active_start_time = ActiveTimeSerializers(label="活动开始时间", help_text="活动开始时间", many=False)
    other_shop_sales_price = serializers.SerializerMethodField(label="其他平台价格")

    def get_other_shop_sales_price(self, instance):
        return instance.other_shop_sales_price / 100.0

    class Meta:
        model = Goods
        fields = ("id", "goods_images_index", "weight", "unit", "goodsname", "price", "sales_price_isvip", "will_sales",
                  "sales_price", "active_start_time", "is_vip_bag", "other_shop_sales_price", "can_sale")


# 购物车需要判断库存
class CartGoodsSerializers(GoodsSerializers):
    stock = serializers.SerializerMethodField(label="获取库存")

    def get_stock(self, instance):
        if instance.company.sign == "womaiwang":
            user = self.context["request"].user
            user_receiver = user.user_receiver_info.filter(default=True)
            if user_receiver.exists():
                user_receiver_obj = user_receiver[0]
                province = user_receiver_obj.province
                ware_house = AreaWareHouse.objects.get(province__name=province)
                if province:
                    stock = Inventory.objects.update_inventory_by_province(str(instance.goodsid), ware_house.p_code)
                    return stock
                else:
                    return 100
            else:
                return 100
        else:
            return instance.stock

    class Meta:
        model = Goods
        fields = ("id", "goods_images_index", "weight", "unit", "goodsname", "price", "sales_price_isvip", "will_sales",
                  "sales_price", "active_start_time", "is_vip_bag", "other_shop_sales_price", "stock", "can_sale")


# 商品属性值
class GoodsAttributeValueSerializers(serializers.ModelSerializer):
    class Meta:
        model = GoodsAttributeValue
        fields = ("id", "value")


# 更新
class CartItemUpdateSerializers(serializers.ModelSerializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    num = serializers.IntegerField(allow_null=False, required=True, label="购物车添加数量", help_text="购物车添加数量")

    def validate_num(self, attrs):
        if attrs > 0:
            return attrs
        else:
            raise serializers.ValidationError("购买数量必须大于0")

    class Meta:
        model = CartItem
        fields = ("user", "num")


# 商品价格
class GoodsPriceSerializers(BaseAttrGoodsPriceSerializers):
    price_attr_value_set = GoodsAttributeValueSerializers(many=True)

    class Meta:
        model = GoodsPrice
        fields = ("price", "sales_price", "sales_price_isvip", "price_attr_value_set", "stock", "id")


# 订单里的商品的属性
class GoodsPriceOrderSerializers(GoodsPriceSerializers):
    class Meta:
        model = GoodsPrice
        fields = ("price_attr_value_set", "id")


# 购物车列表
class CartItemListSerializers(CartItemUpdateSerializers):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    goods = CartGoodsSerializers(read_only=True)
    num = serializers.IntegerField(read_only=True, label="购物车添加数量", help_text="购物车添加数量")
    goods_id = serializers.PrimaryKeyRelatedField(queryset=Goods.objects.all(), write_only=True, label="商品id",
                                                  help_text="商品id", allow_null=True)
    goods_price = GoodsPriceSerializers(read_only=True)

    class Meta:
        model = CartItem
        fields = ("goods", "user", "num", "goods_id", "id", "goods_price")


# 购物车添加
class CartItemSerializers(CartItemUpdateSerializers):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    num = serializers.IntegerField(allow_null=False, required=True, label="购物车添加数量", help_text="购物车添加数量")
    goods_id = serializers.IntegerField(allow_null=True, required=False, label="商品id", help_text="商品id")

    class Meta:
        model = CartItem
        fields = ("goods_id", "user", "num", "id", "goods_price")

    def create(self, validated_data):
        goods_price = validated_data.get("goods_price")
        user = validated_data["user"]
        if goods_price and isinstance(goods_price, GoodsPrice):
            validated_data["goods_id"] = goods_price.goods_id
            cart_item = CartItem.objects.filter(user=user, goods_price_id=goods_price.id, status=1)
        else:
            cart_item = CartItem.objects.filter(user=user, goods_id=validated_data["goods_id"], status=1)
        if cart_item.exists():
            num = validated_data["num"]
            cart_obj = cart_item.first()
            cart_obj.num = F("num") + num  # F(num) + Value(2) 这里的num是这个 所以需要刷新下
            cart_obj.save()
            cart_obj.refresh_from_db()
        else:
            cart_obj = CartItem.objects.create(**validated_data)
        return cart_obj


# 批量删除购物车
class DeleteCartItemSerializers(serializers.Serializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    delete_list = serializers.ListField(label="需要删除的id", help_text="需要删除的id")

    class Meta:
        model = CartItem
        fields = ("delete_list", "user")

    def create(self, validated_data):
        delete_list = validated_data["delete_list"]
        user = self.context["request"].user
        CartItem.objects.filter(id__in=delete_list, user=user).update(
            status=2
        )


# 库存
class InventorySerializers(serializers.ModelSerializer):
    goods_id_list = serializers.ListField(write_only=True, required=True,
                                          error_messages={"required": "此字段必填", "blank": "此字段必填"})
    province = serializers.CharField(write_only=True, label="省份名称", help_text="省份名称", allow_null=False,
                                     allow_blank=False, required=True, error_messages={"required": "请填写收货地址",
                                                                                       "blank": "请填写收货地址",
                                                                                       "null": "请填写收货地址"})
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Inventory
        fields = ("goods_id_list", "province", "user")

    def validate_province(self, attrs):
        if not attrs:
            raise serializers.ValidationError("请先添加购买地址")
        else:
            return attrs

    def create(self, validated_data):
        user = validated_data["user"]
        goods_id_list = validated_data["goods_id_list"]
        province = validated_data.get("province")
        user_receiver = user.user_receiver_info.filter(default=True)
        goods_queryset = Goods.objects.filter(id__in=goods_id_list)
        base_list = []
        womaigoods_queryset = goods_queryset.filter(company__sign="womaiwang")
        if user_receiver.exists():
            user_receiver_obj = user_receiver[0]
            province = user_receiver_obj.province
        ware_house = AreaWareHouse.objects.filter(province__name=province)
        if ware_house:
            ware_house = ware_house.first()
        else:
            for i in goods_id_list:
                base_list.append({"goods_id": i, "num": 0})
            return base_list

        if province:
            if womaigoods_queryset:
                # 获取省份编码
                goods_skus = womaigoods_queryset.values_list("goodsid", flat=True)
                goods_skus = [str(i) for i in goods_skus]
                goods_skus_str = ",".join(goods_skus)
                Inventory.objects.update_inventory_by_province(goods_skus_str, ware_house.p_code)
            for i in goods_id_list:
                try:
                    inventory_obj = Inventory.objects.get(ware_house=ware_house,
                                                          goods_id=i)
                    base_list.append({"goods_id": i, "num": inventory_obj.num})
                except Exception as e:
                    if Goods.objects.get(id=i).company.sign == "womaiwang":
                        base_list.append({"goods_id": i, "num": 0})
                    else:
                        base_list.append({"goods_id": i, "num": 100})
        else:
            for i in goods_id_list:
                base_list.append({"goods_id": i, "num": 100})
        return base_list


class UpdateInventorySerializers(serializers.ModelSerializer):
    province = serializers.PrimaryKeyRelatedField(many=False, read_only=True)


# 配送范围
class AreaSerializers(serializers.ModelSerializer):
    area = serializers.CharField(write_only=True, label="区县名称", help_text="区县名称", allow_null=True,
                                 allow_blank=True, required=False)
    goods_id_list = serializers.ListField(write_only=True, label="商品id列表", help_text="商品id列表",
                                          error_messages={"blank": "此字段不能为空", "required": "此字段不能为空"})
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = VaildArea
        fields = ("area", "goods_id_list", "user")

    def create(self, validated_data):
        user = validated_data["user"]
        goods_id_list = validated_data["goods_id_list"]
        area = validated_data.get("area")
        user_receiver = user.user_receiver_info.filter(default=True)
        base_list = []
        if user_receiver.exists():
            user_receiver_obj = user_receiver[0]  # 默认地址
            for i in goods_id_list:
                goods_obj = Goods.objects.get(id=i)
                if goods_obj.company.sign == "womaiwang":
                    if VaildArea.objects.filter(district__name=user_receiver_obj.county,
                                                goods_type=goods_obj.goodstype).exists():
                        base_list.append({"goods_id": i, "status": True})
                else:
                    base_list.append({"goods_id": i, "status": True})
        else:
            if area:
                for i in goods_id_list:
                    goods_obj = Goods.objects.get(id=i)
                    if goods_obj.company.sign == "womaiwang":
                        if VaildArea.objects.filter(district__name=area,
                                                    goods_type=goods_obj.goodstype).exists():
                            base_list.append({"goods_id": i, "status": True})
                    else:
                        base_list.append({"goods_id": i, "status": True})
            else:
                for i in goods_id_list:
                    base_list.append({"goods_id": i, "status": True})
        return base_list


# 微信支付
class WXPaySerializers(serializers.Serializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    supply_id = serializers.IntegerField(write_only=True, error_messages={"blank": "订单supply_id不能为空"})
    pay_order_model = serializers.ChoiceField(write_only=True, required=False, allow_null=True, allow_blank=True,
                                              choices=orderModel, label="支付订单类型")

    def validate_supply_id(self, attrs):
        user = self.context["request"].user
        if self.initial_data.get("pay_order_model") == "czb":
            try:
                s_order = CzbOrder.objects.get(id=attrs, user=user)
            except CzbOrder.DoesNotExist as e:
                raise serializers.ValidationError("订单未找到")
            except CzbOrder.MultipleObjectsReturned as e:
                raise serializers.ValidationError("数据错误，请联系客服人员")
            if s_order.result == 1:
                raise serializers.ValidationError("此订单已经支付了")
            elif s_order.result == 0:
                return attrs
            else:
                raise serializers.ValidationError("请重新下单")
        else:
            try:
                s_order = SupplyOrder.objects.get(id=attrs, user=user)
            except SupplyOrder.DoesNotExist as e:
                raise serializers.ValidationError("订单未找到")
            except SupplyOrder.MultipleObjectsReturned as e:
                raise serializers.ValidationError("数据错误，请联系客服人员")
            if s_order.wx_pay_type != 0:
                raise serializers.ValidationError("此订单已经支付了")
            else:
                return attrs

    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        pass

    class Meta:
        fields = ("supply_id",)


# 支付结果
class PayResultSerializers(serializers.Serializer):
    supply_id = serializers.IntegerField(write_only=True, error_messages={"blank": "订单supply_id不能为空"})
    pay_order_model = serializers.ChoiceField(write_only=True, required=False, allow_null=True, allow_blank=True,
                                              choices=orderModel, label="支付订单类型")

    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        pass


# 接收微信付款通知H5
class PayAdviceSerializers(serializers.Serializer):
    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        pass


"""OrderedDict([('return_code', 'SUCCESS'), ('return_msg', 'OK'), ('appid', 'wxd229df499f16b723'),
                     ('mch_id', '1310941101'), ('nonce_str', 'txH7WL7XlZGJjiIZ'),
                     ('sign', 'D8F36E0305FE03E345455ADAED9F5574'), ('result_code', 'SUCCESS'),
                     ('transaction_id', '4200000283201903061152347564'),
                     ('out_trade_no', '1310941101201903061600341305'),
                     ('out_refund_no', '1310941101201903061727417439'), ('refund_id', '50000409962019030608621142430'),
                     ('refund_channel', None), ('refund_fee', '6000'), ('coupon_refund_fee', '0'),
                     ('total_fee', '6000'), ('cash_fee', '6000'), ('coupon_refund_count', '0'),
                     ('cash_refund_fee', '6000')])"""


# 银行编号列表
class BankCodeSerializers(serializers.ModelSerializer):
    name = serializers.CharField(read_only=True)
    sign = serializers.CharField(read_only=True)

    class Meta:
        model = BankCode
        fields = "__all__"


# 收藏详情
class CollectDetailSerializers(serializers.ModelSerializer):
    goods = OrderGoodsSerializers(read_only=True)
    update_time = serializers.DateTimeField(format=settings.API_DATETIME_FORMAT, read_only=True)

    # goods_write = serializers.PrimaryKeyRelatedField(source="goods.id")

    class Meta:
        model = Collect
        exclude = ("create_time",)


# 收藏添加修改
class CollectSerializers(serializers.ModelSerializer):
    # user = serializers.HiddenField(default=UserModel.objects.get(id=2))
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Collect
        fields = "__all__"
        # exclude = ("status",)
        validators = [
            UniqueTogetherValidator(queryset=Collect.objects.all(), fields=("user", 'goods', 'status'),
                                    message="已经收藏过了")
        ]


class CollectUpdateSerializers(serializers.ModelSerializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Collect
        fields = ("status", "user")


# 运费
class YFSerializers(serializers.Serializer):
    province = serializers.CharField(write_only=True, label="省份名称", help_text="省份名称", allow_null=True,
                                     required=False, allow_blank=True)
    goods = serializers.IntegerField(write_only=True, label="商品id", help_text="商品id",
                                     error_messages={"blank": "此必填字段", "required": "此必填字段"})
    num = serializers.IntegerField(write_only=True, label="商品数量", help_text="商品数量",
                                   error_messages={"blank": "此必填字段", "required": "此必填字段"})

    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        pass


# 子订单
class ChildOrderSerializers(serializers.ModelSerializer):
    goods = OrderGoodsSerializers(many=False)
    num = serializers.IntegerField(read_only=True, label="数量", help_text="数量")
    price = serializers.SerializerMethodField(label="单价", help_text="单价")
    total_fee = serializers.SerializerMethodField(label="总金额", help_text="总金额")
    after_sale = serializers.ChoiceField(choices=WomaiChildOrder.afterSale, label="售后状态", help_text="售后状态",
                                         read_only=True)
    after_type = serializers.ChoiceField(choices=WomaiChildOrder.afterType, label="售后类型", help_text="售后类型",
                                         read_only=True)
    goods_price = GoodsPriceOrderSerializers(read_only=True)

    # 订单单价
    def get_price(self, obj):
        if obj.wm_order.order_status in [2, 3, 4]:
            # 已付款订单显示订单单价
            return "%.2f" % (obj.price / 100.0)
        else:
            # 未付款订单，商品价格变动，订单价格也变动
            user = obj.wm_order.supply_order.user
            if obj.goods_price:
                sales_price, order_type = obj.goods_price.get_buy_price_attr(user)
            else:
                sales_price, order_type = obj.goods.get_buy_price(user)
            if sales_price != obj.price:
                obj.price = sales_price
                obj.save()
            return "%.2f" % (sales_price / 100.0)

    # 订单总价
    def get_total_fee(self, obj):
        if obj.wm_order.order_status in [2, 3, 4]:
            # 已付款订单显示订单单价
            return "%.2f" % (obj.total_fee / 100.0)
        else:
            # 未付款订单，商品价格变动，订单价格也变动
            user = obj.wm_order.supply_order.user
            if obj.goods_price:
                total_fee, price, is_promotion, order_type = obj.goods.get_total_fee_price(user, obj.num)
            else:
                total_fee, price, is_promotion, order_type = obj.goods.get_total_fee_price(user, obj.num)
            if total_fee != obj.total_fee:
                obj.total_fee = total_fee
                obj.save()
            return "%.2f" % (total_fee / 100.0)

    class Meta:
        model = WomaiChildOrder
        fields = ("goods", "num", "price", "total_fee", "id", "after_sale", "after_type", "goods_price")


# 父订单的基础类
class MainOrderBaseSerializers(serializers.ModelSerializer):
    order_num = serializers.SerializerMethodField(read_only=True, label="数量")
    supply_id = serializers.SerializerMethodField(read_only=True, label="主订单id")

    def get_supply_id(self, instance):
        return instance.supply_order_id

    # def get_supply_id(self, instance):
    #     # 如果是待付款订单
    #     if instance.order_status == 1:
    #         goods_mun_list = [{"goods": i.goods, "num": i.num} for i in instance.child_order.all()]
    #         shop_goods_num_list = [{"data": goods_mun_list, "company_sign": instance.company.sign}]
    #         province = instance.supply_order.receipt_place.province
    #         shop_goods_num_list = YF.objects.get_post_fee(shop_goods_num_list, province)
    #         shop_goods_num = shop_goods_num_list[0]
    #         receivable_post_fee = shop_goods_num.get("receivable_post_fee")  # 应收运费
    #         post_fee = shop_goods_num.get("post_fee")  # 实收运费
    #         shop_total_fee = instance.get_total_price_by_child()  # 这家卖家总价格
    #         # shop_total_fee = 0
    #         # for data in shop_goods_num.get("data"):
    #         #     goods = data.get("goods")
    #         #     total_fee, price, is_promotion, order_type = goods.get_total_fee_price(user, data.get("num"))
    #         #     shop_total_fee += total_fee
    #         shop_payment = post_fee + shop_total_fee
    #
    #         # 如果子订单的应付款金额和主订单的付款金额一样
    #         if shop_payment == instance.supply_order.payment:
    #             return instance.supply_order_id
    #         # 如果不一样
    #         else:
    #             # 基础订单
    #             base_order = SupplyOrder.objects.create_order(
    #                 instance.supply_order.user, buyer_message=instance.supply_order.buyer_message
    #             )
    #             base_order.pose_fee = instance.post_fee
    #             base_order.total_fee = instance.total_fee
    #             base_order.is_active = True
    #             base_order.payment = instance.payment
    #             base_order.created_time = instance.supply_order.created_time
    #             base_order.save()
    #             # 绑定关系
    #             instance.post_fee = post_fee
    #             instance.receivable_post_fee = receivable_post_fee
    #             instance.total_fee = shop_total_fee
    #             instance.payment = shop_payment
    #             instance.supply_order = base_order
    #             instance.save()
    #             return base_order.id
    #     else:
    #         return instance.supply_order_id

    def get_order_num(self, instance):
        return instance.child_order.aggregate(num=Sum("num")).get("num")


# 订单列表(订单购买)
class MainOrderSerializers(MainOrderBaseSerializers):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    child_order = ChildOrderSerializers(many=True, read_only=True)
    source = serializers.ChoiceField(choices=["cart", "normal"], write_only=True, required=True, allow_blank=False,
                                     allow_null=False)
    province = serializers.CharField(write_only=True, required=False, allow_null=True, allow_blank=True, label="省份")

    goods_mun_list = serializers.ListField(write_only=True)
    buyer_message = serializers.CharField(label="买家留言", help_text="买家留言", read_only=True)
    payment = serializers.SerializerMethodField(label="总计应付金额", help_text="总计应付金额", read_only=True)
    order_status = serializers.IntegerField(read_only=True, label="订单状态", help_text="订单状态")
    shop_name = serializers.SerializerMethodField(label="商家名字", help_text="商家名字")

    class Meta:
        model = WomaiOrder
        fields = ("user", "source", "province", "goods_mun_list", "payment", "order_status",
                  "child_order", "shop_name", "id", "order_num", "supply_id", "buyer_message")

    def get_payment(self, obj):
        return obj.payment / 100.0

    def get_shop_name(self, obj):
        return obj.company.name

    def get_buyer_message(self, obj):
        if obj.buyer_message:
            return obj.buyer_message
        else:
            return ""

    # 拆单
    @staticmethod
    def split_order(goods_mun_list):
        """
        # [{"goodsid": 90, "num": 3, "goods_price":5}]
        :param goods_mun_list: [{"goodsid": 167, "num": 3, "goods_price":3}, {"goodsid": 2, "num": 2, "goods_price":2}]
        :return: [{"company_sign":"公司sign", "data": [{"goods":goods_obj, "num":3, "goods_price":1},{"goods":goods_obj, "num":2, "goods_price":2}]},]
        """
        goods_id_list = [i.get("goodsid") for i in goods_mun_list]
        goods_qs = Goods.objects.filter(id__in=goods_id_list)  # 获取提交上来的商品
        goods_company = goods_qs.values_list("company__sign").distinct().order_by("company__sign")  # 按公司去重
        base_list = []
        for company in goods_company:
            goods_list = goods_qs.filter(company__sign=company[0])  # 相同公司的商品
            same_company_goods_num_list = []
            for goods in goods_list:
                for goods_num in goods_mun_list:
                    if goods.id == goods_num["goodsid"]:
                        num = goods_num["num"]
                        goods_price = goods_num.get("goods_price", None)
                        same_company_goods_num_list.append({"goods": goods, "num": num, "goods_price": goods_price})
            base_list.append({"company_sign": company[0], "data": same_company_goods_num_list})
        # [{"company_sign":"公司sign", "data": [{"goods":goods_obj, "num":3, "goods_price":1},{"goods":goods_obj, "num":2}]},]
        return base_list

    def create(self, validated_data):
        goods_mun_list = validated_data["goods_mun_list"]
        source = validated_data["source"]
        user = validated_data["user"]
        # buyer_message = validated_data["buyer_message"]
        province = validated_data.get("province", None)
        province_default = ReceiverPlace.objects.filter(user=user, default=True)
        if province_default.exists():
            province = province_default[0].province
        # company_goods_num_list = self.split_order(goods_mun_list)

        company_goods_num_list = YF.objects.get_post_fee(goods_mun_list, province)
        # 基础订单
        base_order = SupplyOrder.objects.create_order(
            user
        )
        # 主订单
        post_fee = 0
        total_fee = 0
        for i in company_goods_num_list:
            company_total_fee = 0
            tid = funcUtils.unique_value
            main_order = WomaiOrder.objects.create(
                tid=tid,
                supply_order=base_order,
                post_fee=i.get("post_fee"),
                company=Company.objects.get(sign=i.get("company_sign")),
                buyer_message=i.get("buyer_message")
            )
            data_list = i.get("data")
            for data in data_list:
                # "data": [{"goods":goods_obj, "num":3, "goods_price":1},{"goods":goods_obj, "num":2, "goods_price":2}]
                oid = funcUtils.unique_value
                goods = data.get("goods")
                num = data.get("num")
                goods_price = data.get("goods_price")
                if goods_price:
                    goods_price_obj = GoodsPrice.objects.get(id=goods_price)
                    result = goods_price_obj.get_total_fee_price(user, data.get("num"))
                    cost = goods_price_obj.cost
                    goods_price_obj.stock = F("stock") - num
                    goods_price_obj.save()
                else:
                    result = goods.get_total_fee_price(user, data.get("num"))
                    cost = goods.cost

                one_goods_total_fee, one_goods_price, is_promotion, order_type = result
                child_order = WomaiChildOrder.objects.create(
                    goods_price_id=goods_price,
                    goods=goods,
                    oid=oid,
                    num=num,
                    wm_order=main_order,
                    total_fee=one_goods_total_fee,
                    price=one_goods_price,
                    is_promotion=is_promotion,
                    order_type=order_type,
                    cost=cost
                )
                if i.get("company_sign") != "womaiwang":
                    goods.stock = F("stock") - num
                    goods.save()
                total_fee += child_order.total_fee  # 总商品价格
                company_total_fee += child_order.total_fee  # 按公司总价格
            # 更新主订单数据
            main_order.total_fee = company_total_fee
            main_order.post_fee = i.get("post_fee")
            main_order.payment = i.get("post_fee") + company_total_fee
            main_order.receivable_post_fee = i.get("receivable_post_fee")  # 应收运费
            main_order.save()
            # 我买网的数据调接口
            if i.get("company_sign") == "womaiwang":
                data = WomaiOrder.objects.add_trade(main_order)
                content = mai_api.goods_add(data)
                result = content.get("result")
                if result == "true":
                    ordercode = content.get("ordercode")
                    main_order.ordercode = ordercode
                    main_order.save()
                else:
                    # 报错的话 订单删除
                    main_order.order_status = 6
                    main_order.save()
                    raise serializers.ValidationError(content.get("error_response").get("memo"))
            # 更新总订单数据
            post_fee += i.get("post_fee")  # 总运费
        base_order.pose_fee = post_fee
        base_order.total_fee = total_fee
        base_order.is_active = True
        base_order.payment = total_fee + post_fee
        base_order.save()
        if source == "cart":  # 如果来源是购物车就把购物车里的数据修改状态
            goods_id_list = [i.get("goodsid") for i in goods_mun_list]
            CartItem.objects.filter(goods_id__in=goods_id_list, user=user).update(status=2)
        return base_order


# 订单详情
class MainOrderDetailsSerializers(MainOrderBaseSerializers):
    receiver = serializers.SerializerMethodField(read_only=True, label="收货人信息", help_text="收货人信息")
    created_time = serializers.SerializerMethodField(read_only=True, label="创建时间", help_text="创建时间")
    pay_time = serializers.SerializerMethodField(read_only=True, label="付款时间", help_text="付款时间")
    pay_type = serializers.SerializerMethodField(read_only=True, label="支付类型", help_text="支付类型")
    shop_tel = serializers.SerializerMethodField(label="商家电话", help_text="商家电话", read_only=True)
    shop_name = serializers.SerializerMethodField(label="商家名称", help_text="商家名称", read_only=True)
    tid = serializers.CharField(read_only=True, label="订单号", help_text="订单号")
    child_order = ChildOrderSerializers(many=True, read_only=True)
    logistics = serializers.SerializerMethodField(read_only=True, label="物流信息", help_text="物流信息")
    dead_time = serializers.SerializerMethodField(read_only=True, label="过期时间", help_text="过期时间")
    payment = serializers.SerializerMethodField(read_only=True, label="实付金额", help_text="实付金额")
    total_fee = serializers.SerializerMethodField(read_only=True, label="商品总价", help_text="商品总价")
    post_fee = serializers.SerializerMethodField(read_only=True, label="主订单运费合计", help_text="主订单运费合计")

    @staticmethod
    def logistics_content(order):
        if order.company.sign == "womaiwang":
            post_company = "我买网配送"
        else:
            post_company = order.logistics.post_company.name
        odd_numbers = order.logistics.code
        return odd_numbers, post_company

    @staticmethod
    def logistics_extend_content(order):
        remark = order.logistics.logistics_record.all().first().remark
        create_time = order.logistics.logistics_record.all().first().create_time
        return remark, create_time

    def get_logistics(self, obj):
        if obj.company.sign == "womaiwang":
            if obj.order_status != 1 and obj.order_status != 5 and obj.order_status != 6:
                Logistics.objects.logistics_detail_wm(obj)  # 更新物流详情
                odd_numbers, post_company = self.logistics_content(obj)
                remark, create_time = self.logistics_extend_content(obj)
                return {"odd_numbers": odd_numbers, "post_company": post_company, "remark": remark,
                        "create_time": create_time}
            else:
                return {}
        else:
            if hasattr(obj,
                       "logistics") and obj.logistics.logistics_record.exists() and obj.order_status == 3 or obj.order_status == 4:
                # user = self.context.get("user")
                Logistics.objects.logistics_detail(obj)  # 更新物流详情
                odd_numbers, post_company = self.logistics_content(obj)
                remark, create_time = self.logistics_extend_content(obj)
                return {"odd_numbers": odd_numbers, "post_company": post_company, "remark": remark,
                        "create_time": create_time}
            else:
                return {}

    def get_receiver(self, obj):
        kwargs = {"many": False, "context": self.context}
        return ReceiverPlaceSerializers(obj.supply_order.receipt_place, **kwargs).data

    def get_pay_time(self, obj):
        if obj.supply_order.wx_pay_type == 0:
            return ""
        return obj.supply_order.pay_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_created_time(self, obj):
        return obj.supply_order.created_time.strftime("%Y-%m-%d %H:%M:%S")

    def get_dead_time(self, obj):
        create_time = obj.supply_order.created_time
        delta = datetime.timedelta(hours=2)
        end_time = create_time + delta
        now_time = datetime.datetime.now()
        if now_time > end_time:
            return "0,0,0"
        d = (end_time - now_time)
        c_count = d.seconds
        h = c_count / 3600
        h = math.floor(h)
        if h == 0:
            m = c_count / 60
            m = math.floor(m)
            if m > 0:
                s = c_count % (m * 60)
            else:
                s = c_count
        else:
            s = c_count - h * 3600
            m = s / 60
            m = math.floor(m)
            if m > 0:
                s %= (m * 60)
        return "{h},{m},{s}".format(h=h, m=m, s=s)

    def get_pay_type(self, obj):
        return obj.supply_order.get_wx_pay_type_display()

    def get_shop_tel(self, obj):
        return obj.company.tel

    def get_shop_name(self, obj):
        return obj.company.name

    def get_payment(self, obj):
        return obj.payment / 100.0

    def get_total_fee(self, obj):
        return obj.total_fee / 100.0

    def get_post_fee(self, obj):
        return obj.post_fee / 100.0

    class Meta:
        model = WomaiOrder
        fields = ("receiver", "child_order", "pay_time", "pay_type", "tid", "shop_tel", "post_fee", "order_status",
                  "created_time", "shop_name", "receivable_post_fee", "dead_time",
                  "payment", "total_fee", "order_num", "supply_id", "logistics")

    def update(self, instance, validated_data):
        if validated_data.get("order_status"):
            if validated_data["order_status"] == 5:
                if instance.order_status == 2:
                    instance.order_status = 2
                    instance.save()
                else:
                    raise serializers.ValidationError("只有代付款的商品可以取消订单")


# 更新订单状态
class OrderStatusSerializers(serializers.ModelSerializer):
    orderStatus = ((1, "待付款"), (2, "待发货"), (3, "待收货"), (4, "已完成"), (5, "已取消"), (6, "删除"))
    order_status = serializers.ChoiceField(choices=orderStatus, write_only=True, label="订单状态")

    def validate_order_status(self, attrs):
        if attrs == 5:
            instance = self.instance
            # 只有在待付款的情况下 才能取消订单
            if instance.order_status == 1:
                return attrs
            elif instance.order_status == 5:
                raise serializers.ValidationError("此订单已经取消")
            else:
                raise serializers.ValidationError("此订单不可取消")
        else:
            return attrs

    class Meta:
        model = WomaiOrder
        fields = ("order_status",)

    def update(self, instance, validated_data):
        order_status = validated_data["order_status"]
        if order_status == 6 or order_status == "6":
            instance.is_delete = True
        elif order_status == 5 or order_status == "5":
            instance.cancel_order_obj()
        instance.order_status = order_status
        instance.save()
        return instance


# 立刻购买
class BuyNowSerializers(serializers.Serializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    goods_mun_list = serializers.ListField(write_only=True)
    province = serializers.CharField(write_only=True, required=False, allow_null=True, allow_blank=True, label="省份")

    class Meta:
        fields = ("user", "goods_mun_list", "province")

    def validate_goods_mun_list(self, goods_mun_list):
        """
        :param goods_mun_list:
        :return: "goods_mun_list": [{"company_sign":"jinkoujiaju","data": [{"goods": 18, "num": 1},
        {"goods": 90, "num": 3, "goods_price":5}]}]
        """
        for i in goods_mun_list:
            data_list = i.get("data")
            if data_list:
                for data_one in data_list:
                    if data_one.get("goods"):
                        goods_obj = Goods.objects.get(id=data_one.get("goods"))
                        data_one["goods"] = goods_obj
                    else:
                        raise serializers.ValidationError("goods字段必填")
                    if data_one.get("num"):
                        data_one["num"] = int(data_one.get("num"))
                    else:
                        raise serializers.ValidationError("num字段必填")
                    goods_obj = data_one["goods"]
                    if data_one.get("goods_price"):
                        try:
                            goods_price_obj = goods_obj.goods_price_set.get(id=data_one.get("goods_price"))
                            data_one["goods_price"] = goods_price_obj
                        except Exception as e:
                            print(e)
                            raise serializers.ValidationError("此商品的goods_price不对应")
                    else:
                        if goods_obj.goods_price_set.exists():
                            raise serializers.ValidationError("此商品的goods_price必填")
            else:
                raise serializers.ValidationError("data字段缺少内容")
        return goods_mun_list

    def create(self, validated_data):
        company_goods_num_list = validated_data["goods_mun_list"]
        user = validated_data["user"]
        province = validated_data.get("province", None)
        province_default = ReceiverPlace.objects.filter(user=user, default=True)
        if province_default.exists():
            province = province_default[0].province
        company_goods_num_list = YF.objects.get_post_fee(company_goods_num_list, province)
        kwargs = {"many": False, "context": self.context}
        for i in company_goods_num_list:
            company_total_fee = 0
            data_list = i.pop("data")
            order_num = 0
            for data in data_list:
                goods = data.get("goods")
                goods_price = data.get("goods_price")
                if goods_price:
                    one_goods_total_fee, one_goods_price, is_promotion, order_type = \
                        goods_price.get_total_fee_price(user, data.get("num"))
                    data["goods_price"] = GoodsPriceSerializers(goods_price, **kwargs).data
                else:
                    one_goods_total_fee, one_goods_price, is_promotion, order_type = \
                        goods.get_total_fee_price(user, data.get("num"))
                    data["goods_price"] = None
                data["goods"] = OrderGoodsSerializers(goods, **kwargs).data
                data["total_fee"] = one_goods_total_fee / 100.0
                data["price"] = one_goods_price / 100.0
                company_total_fee += one_goods_total_fee
                order_num += data["num"]
            company_obj = Company.objects.get(sign=i.get("company_sign"))
            i["total_fee"] = company_total_fee / 100.0  # 商品价格
            i["shop_name"] = company_obj.name
            i["shop_tel"] = company_obj.tel
            i["child_order"] = data_list
            i["order_num"] = order_num
            i["receivable_post_fee"] = i.get("receivable_post_fee") / 100.0
            i["post_fee"] = i.get("post_fee") / 100.0
        return company_goods_num_list

    def update(self, instance, validated_data):
        pass


# 订单购买
class SubmitOrderSerializers(BuyNowSerializers):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    goods_mun_list = serializers.ListField(write_only=True)
    province = serializers.CharField(write_only=True, required=False, allow_null=True, allow_blank=True, label="省份")
    source = serializers.ChoiceField(choices=["cart", "normal"], write_only=True, required=True, allow_blank=False,
                                     allow_null=False)

    def create(self, validated_data):
        company_goods_num_list = validated_data["goods_mun_list"]
        user = validated_data["user"]
        province = validated_data.get("province", None)
        source = validated_data["source"]
        province_default = ReceiverPlace.objects.filter(user=user, default=True)
        if province_default.exists():
            province = province_default[0].province
        company_goods_num_list = YF.objects.get_post_fee(company_goods_num_list, province)
        base_order = SupplyOrder.objects.create_order(
            user
        )
        # 主订单
        post_fee = 0
        total_fee = 0
        goods_list = []
        goods_price_list = []
        for i in company_goods_num_list:
            company_total_fee = 0
            tid = funcUtils.unique_value
            main_order = WomaiOrder.objects.create(
                tid=tid,
                supply_order=base_order,
                post_fee=i.get("post_fee"),
                company=Company.objects.get(sign=i.get("company_sign")),
                buyer_message=i.get("buyer_message")
            )
            data_list = i.get("data")
            for data in data_list:
                oid = funcUtils.unique_value
                goods = data.get("goods")
                num = data.get("num")
                goods_price = data.get("goods_price")
                goods_list.append(goods)
                goods_price_list.append(goods_price)
                if goods_price:
                    result = goods_price.get_total_fee_price(user, data.get("num"))
                    cost = goods_price.cost
                    goods_price.stock = F("stock") - num
                    goods_price.save()
                else:
                    result = goods.get_total_fee_price(user, data.get("num"))
                    cost = goods.cost
                one_goods_total_fee, one_goods_price, is_promotion, order_type = result
                child_order = WomaiChildOrder.objects.create(
                    goods_price=goods_price,
                    goods=goods,
                    oid=oid,
                    num=num,
                    wm_order=main_order,
                    total_fee=one_goods_total_fee,
                    price=one_goods_price,
                    is_promotion=is_promotion,
                    order_type=order_type,
                    cost=cost
                )
                if i.get("company_sign") != "womaiwang":
                    goods.stock = F("stock") - num
                    goods.save()
                total_fee += child_order.total_fee  # 总商品价格
                company_total_fee += child_order.total_fee  # 按公司总价格
            # 更新主订单数据
            main_order.total_fee = company_total_fee
            main_order.post_fee = i.get("post_fee")
            main_order.payment = i.get("post_fee") + company_total_fee
            main_order.receivable_post_fee = i.get("receivable_post_fee")  # 应收运费
            main_order.save()
            # 我买网的数据调接口
            if i.get("company_sign") == "womaiwang":
                data = WomaiOrder.objects.add_trade(main_order)
                content = mai_api.goods_add(data)
                result = content.get("result")
                if result == "true":
                    ordercode = content.get("ordercode")
                    main_order.ordercode = ordercode
                    main_order.save()
                else:
                    # 报错的话 订单删除
                    main_order.order_status = 6
                    main_order.save()
                    raise serializers.ValidationError(content.get("error_response").get("memo"))
            # 更新总订单数据
            post_fee += i.get("post_fee")  # 总运费
        base_order.pose_fee = post_fee
        base_order.total_fee = total_fee
        base_order.is_active = True
        base_order.payment = total_fee + post_fee
        base_order.save()
        if source == "cart":  # 如果来源是购物车就把购物车里的数据修改状态
            CartItem.objects.filter(
                Q(goods_price__in=goods_price_list) | Q(goods__in=goods_list, goods_price__isnull=True)).update(
                status=2)
        return base_order

    def update(self, instance, validated_data):
        pass


# 基础订单
class BaseOrderSerializers(serializers.ModelSerializer):
    payment = serializers.IntegerField(label="实付金额", help_text="实付金额", read_only=True)

    def get_payment(self, obj):
        return obj.payment / 100.0

    class Meta:
        model = SupplyOrder
        fields = ("id", "wx_pay_type", "payment")


# 收益里的订单记录
class IncomeSerializers(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(label="创建时间", help_text="创建时间", read_only=True,
                                            format=settings.API_DATETIME_FORMAT)
    income = serializers.SerializerMethodField(label="收入", help_text="收入", read_only=True)
    sales = serializers.SerializerMethodField(label="销售额", help_text="销售额", read_only=True)
    order_num = serializers.SerializerMethodField(label="订单数", help_text="订单数", read_only=True)
    sales_context = serializers.SerializerMethodField(label="销售额上下文", help_text="销售额上下文", read_only=True)
    income_context = serializers.SerializerMethodField(label="销售额上下文", help_text="销售额上下文", read_only=True)
    order_context = serializers.SerializerMethodField(label="销售额上下文", help_text="销售额上下文", read_only=True)

    def get_income(self, obj):
        income = obj.income / 100
        return "%.2f" % income

    # 有哪个用户带来的收益
    def income_by_user(self, obj):
        if obj.income_type == 1:
            return obj.base_order.user
        else:
            return obj.lower_income.user

    def get_sales_context(self, obj):
        user = self.income_by_user(obj)
        name = user.name
        user_code = user.id
        return "{name} (ID:{user_code}) 贡献销售额".format(name=name, user_code=user_code)

    def get_income_context(self, obj):
        user = self.income_by_user(obj)
        name = user.name
        user_code = user.id
        return "{name} (ID:{user_code}) 贡献收益".format(name=name, user_code=user_code)

    def get_order_context(self, obj):
        user = self.income_by_user(obj)
        name = user.name
        user_code = user.id
        return "{name} (ID:{user_code}) 贡献1笔订单".format(name=name, user_code=user_code)

    def get_sales(self, obj):
        total_fee = obj.order.total_fee
        total_fee = total_fee / 100
        return "%.2f" % total_fee

    def get_order_num(self, obj):
        return 1

    class Meta:
        model = OrderIncome
        fields = ("id", "income", "sales", "order_num", "sales_context", "create_time",
                  "income_context", "order_context", "submit_state")


# 提现记录
class TransferRecordSerializers(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(format=settings.API_DATETIME_FORMAT, read_only=True, label="提现金额",
                                            help_text="提现金额")
    cash = serializers.SerializerMethodField(read_only=True, label="提现金额", help_text="提现金额")

    def get_cash(self, obj):
        return "%.2f" % (obj.cash / 100.0)

    class Meta:
        model = TransferRecord
        fields = ("create_time", "cash")


# 后台

# 后台订单
class AdminOrderSerializers(serializers.ModelSerializer):
    tid = serializers.CharField(read_only=True, label="订单号")
    order_status = serializers.SerializerMethodField(read_only=True, label="订单状态")
    create_time = serializers.SerializerMethodField(read_only=True, label="创建时间")
    child_order = ChildOrderSerializers(many=True, read_only=True)

    def get_create_time(self, instance):
        return instance.supply_order.created_time

    def get_order_status(self, instance):
        return instance.get_order_status_display()

    class Meta:
        model = WomaiOrder
        fields = ("tid", "order_status", "child_order", "id", "create_time")


# 子订单管理(含售后)
class WomaiChildOrderSerializers(serializers.ModelSerializer):
    """
    子订单
    """
    after_sale = serializers.IntegerField(label="售后", read_only=True)
    after_type = serializers.IntegerField(label="售后类型", read_only=True)
    goods = GoodsSerializers(read_only=True, label="商品", many=False)
    oid = serializers.CharField(read_only=True, label="订单号")
    price = serializers.SerializerMethodField(label="单价", read_only=True)
    total_fee = serializers.SerializerMethodField(label="总价", read_only=True)
    after_type_desc = serializers.SerializerMethodField(label="售后类型", read_only=True)
    after_sale_desc = serializers.SerializerMethodField(label="售后状态", read_only=True)
    num = serializers.IntegerField(read_only=True, label="数量")
    tel = serializers.SerializerMethodField(label="手机号", read_only=True)
    name = serializers.SerializerMethodField(label="姓名", read_only=True)
    update_time = serializers.DateTimeField(read_only=True, format=settings.API_DATETIME_FORMAT)
    apply_refund_time = serializers.DateTimeField(read_only=True, format=settings.API_DATETIME_FORMAT)
    shop_remark = serializers.CharField(read_only=True, label="商家标记的备注")
    refund = serializers.SerializerMethodField(label="退款信息", read_only=True)
    shop_name = serializers.SerializerMethodField(label="商家名字", read_only=True)
    shop_tel = serializers.SerializerMethodField(label="商家电话", read_only=True)

    def get_shop_name(self, instance):
        return instance.goods.company.name

    def get_refund(self, instance):
        if instance.refund:
            kwargs = {"many": False, "context": self.context}
            return RefundRecordSerializers(instance.refund, **kwargs).data
        else:
            return {
                "refund_fee": "0.0"
            }

    def get_name(self, instance):
        return instance.wm_order.supply_order.receipt_place.receiver_name

    def get_tel(self, instance):
        return instance.wm_order.supply_order.receipt_place.receiver_mobile

    def get_after_type_desc(self, instance):
        return instance.get_after_type_display() if instance.get_after_type_display() else "不需要退款"

    def get_after_sale_desc(self, instance):
        return instance.get_after_sale_display()

    def get_price(self, instance):
        return instance.price / 100.0

    def get_total_fee(self, instance):
        return instance.total_fee / 100.0

    def get_shop_tel(self, instance):
        return instance.goods.company.tel

    class Meta:
        model = WomaiChildOrder
        fields = ("after_sale", "after_type", "id", "goods", "price", "total_fee", "num", "tel", "name", "oid",
                  "after_type_desc", "update_time", "shop_remark", "refund", "after_sale_desc", "shop_name",
                  "apply_refund_time", "order_type", "shop_tel")


# 用户发起售后
class UpdateWomaiChildOrderSerializers(serializers.ModelSerializer):
    after_sale = serializers.ChoiceField(label="售后", choices=WomaiChildOrder.afterSale, write_only=True)
    after_type = serializers.ChoiceField(label="售后类型", choices=WomaiChildOrder.afterType, write_only=True)
    tel = serializers.SerializerMethodField(read_only=True)

    def get_tel(self, instance):
        return instance.goods.company.tel

    def validate(self, attrs):
        attrs["apply_refund_time"] = datetime.datetime.now()
        if self.instance.order_type == 2:
            raise serializers.ValidationError("会员礼包不进行退款")
        else:
            return attrs

    class Meta:
        model = WomaiChildOrder
        fields = ("after_sale", "after_type", "tel")


# 购物退款后台退款
class RefundSerializers(WomaiChildOrderSerializers):
    after_sale = serializers.ChoiceField(label="状态", help_text="售后状态", choices=WomaiChildOrder.afterSale)
    refund_fee = serializers.DecimalField(label="退款金额", help_text="退款金额", write_only=True, max_digits=10,
                                          allow_null=True, required=False,
                                          decimal_places=2, error_messages={"decimal_places": "退款金额最多为两位小数",
                                                                            "max_decimal_places": "退款金额不超过两位小数"})
    shop_remark = serializers.CharField(write_only=True, max_length=256, label="商家备注", allow_blank=True,
                                        allow_null=True, required=False)
    post_fee_status = serializers.ChoiceField(choices=WomaiChildOrder.postFeeStatus, label="退运费状态", allow_blank=True,
                                              allow_null=True, required=False)

    def get_post_fee_status(self, instance):
        if instance.post_fee_status and instance.post_fee_status == 2:
            return 2
        else:
            return 1

    def get_after_sales(self, attr):
        try:
            attr >= 1
            return attr
        except Exception as e:
            print(e)
            raise serializers.ValidationError("退款状态参数错误")

    # 验证相同的是否退过运费
    def validate_post_fee_status(self, attrs):
        if attrs == 2 or attrs == "2":
            if WomaiChildOrder.objects.filter(wm_order=self.instance.wm_order, post_fee_status=2).exists():
                serializers.ValidationError("运费在其他订单中已经退过")
            return attrs
        return attrs

    def validate_shop_remark(self, attrs):
        return mark_safe(attrs)

    def validate_refund_fee(self, attrs):
        if attrs:
            attrs = int(attrs * 100)
            if self.initial_data["after_sale"] == 4 or self.initial_data["after_sale"] == "4":
                if attrs > self.instance.total_fee:
                    raise serializers.ValidationError("退款金额不能大于购买金额")
                else:
                    return str(attrs)
            return str(attrs)
        else:
            return attrs

    # def validate(self, attrs):
    #     if self.instance.goods.is_vip_bag:
    #         raise serializers.ValidationError("会员礼包不进行退款")
    #     else:
    #         return attrs

    def wx_refund(self, total_fee, refund_fee, out_refund_no, out_trade_no):
        """
        微信退款
        :return:
        """
        status, message = RefundRecord.objects.wx_refund(total_fee, refund_fee, out_refund_no, out_trade_no)
        if not status:
            raise serializers.ValidationError(message)

    def tl_refund(self, refund_amount, order_no, tl_pay_record_obj, out_refund_no):
        """
        通联退款
        :param refund_amount: 退款金额
        :param order_no: 支付时的订单号
        :param tl_pay_record_obj: 支付对象
        :param out_refund_no: 商户退款订单号
        :return:
        """
        status, message = TLRefundRecord.objects.tl_refund(refund_amount, order_no, tl_pay_record_obj, out_refund_no)
        if not status:
            raise serializers.ValidationError(message)

    def yl_refund(self, refund_amount, pay_record_obj, refundOrderId):
        """
        银联退款
        :param refund_amount: 退款金额
        :param order_no: 支付时的订单号
        :param pay_record_obj: 支付对象
        :return:
        """
        status, message = YLRefundRecord.objects.yl_refund(refund_amount, pay_record_obj.out_trade_no, refundOrderId)
        if not status:
            raise serializers.ValidationError(message)

    def update(self, instance, validated_data):
        total_fee = instance.wm_order.supply_order.payment
        goods_refund_fee = int(validated_data.get("refund_fee", 0))
        after_sale = validated_data["after_sale"]
        shop_remark = validated_data.get("shop_remark", "")
        post_fee_status = validated_data.get("post_fee_status", "")  # 退运费状态
        if post_fee_status == 2:
            refund_fee = goods_refund_fee + instance.wm_order.post_fee
        else:
            refund_fee = goods_refund_fee
        if after_sale == 4:
            supply_order_obj = instance.wm_order.supply_order
            out_trade_no = supply_order_obj.out_trade_no
            # 通联
            if supply_order_obj.wx_pay_type == 3:
                out_refund_no = funcUtils.unique_value  # 退款订单号
                tl_pay_record_obj = TLPayRecord.objects.get(orderNo=out_trade_no, is_pay=True)
                self.tl_refund(refund_fee, out_trade_no, tl_pay_record_obj, out_refund_no)
            # 微信
            elif supply_order_obj.wx_pay_type == 1:
                # 只能退款一次
                out_refund_no = wx_pay.out_trade_no  # 退款订单号
                self.wx_refund(total_fee, refund_fee, out_refund_no, out_trade_no)
            elif supply_order_obj.wx_pay_type == 4:
                out_refund_no = YLClient().unique_value  # 退款订单号
                yl_pay_record_obj = YLPayRecord.objects.get(out_trade_no=out_trade_no, is_pay=True)
                self.yl_refund(refund_fee, yl_pay_record_obj, out_refund_no)
            else:
                raise serializers.ValidationError("退款失败, 请重试")
            # 记录退款
            refund_instance = RefundRecord.objects.create_refund(
                refund_fee=refund_fee,
                refund_type=supply_order_obj.wx_pay_type,
                out_refund_no=out_refund_no
            )
            instance.refund = refund_instance
            instance.after_sale = after_sale
            instance.shop_remark = shop_remark
            instance.save()
            # instance.wm_order.total_fee = F("total_fee") - goods_refund_fee
            # instance.wm_order.supply_order.total_fee = F("total_fee") - goods_refund_fee
            # instance.wm_order.supply_order.save()
            # 标记收益退款
            OrderIncome.objects.update_refund_income(instance)
            # 更新升级绩效
            instance.wm_order.supply_order.user.update_user_perf(goods_refund_fee, operation="-")
        else:
            instance.after_sale = after_sale
            instance.shop_remark = shop_remark
            instance.save()
        # 3换货成功 4 退款成功
        if instance.after_sale == 3 or instance.after_sale == 4:
            # 如果此订单中除了退款成功之外没有其他的子订单，全部变成售后完成，如果还有其他的子订单，现在的状态是什么就显示什么
            if not WomaiChildOrder.objects.filter(wm_order=self.instance.wm_order).exclude(after_sale=4).exists():
                instance.wm_order.order_status = 6
                instance.wm_order.save()
        return instance

    class Meta:
        model = WomaiChildOrder
        fields = ("after_sale", "after_type", "id", "goods", "price", "total_fee", "num", "tel", "name", "oid",
                  "after_type_desc", "update_time", "shop_remark", "refund", "after_sale_desc", "refund_fee",
                  "post_fee_status")


# 物流信息
class CreateLogisticsSerializers(serializers.ModelSerializer):
    order = serializers.PrimaryKeyRelatedField(write_only=True, label="订单", queryset=WomaiOrder.objects.all())

    class Meta:
        model = Logistics
        exclude = ("order", "stationname")


# 物流公司列表
class PostCompanySerializers(serializers.ModelSerializer):
    class Meta:
        model = PostCompany
        fields = "__all__"


# 物流信息
class LogisticsSerializers(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(read_only=True, format=settings.API_DATETIME_FORMAT)
    post_company_id = serializers.IntegerField(label="邮递公司id", help_text="邮递公司id")
    order_id = serializers.IntegerField(label="订单id", help_text="订单id")

    class Meta:
        model = Logistics
        fields = ("id", "code", "post_company_id", "create_time", "order_id")


# 后台订单
class AdminMainOrderSerializers(serializers.ModelSerializer):
    goods = serializers.SerializerMethodField(read_only=True)
    tid = serializers.CharField(read_only=True, label="订单号")
    order_status = serializers.CharField(read_only=True, label="订单状态")
    logistics = LogisticsSerializers(many=False)
    receiverplace = serializers.SerializerMethodField()
    total_cost = serializers.SerializerMethodField()
    pay_time = serializers.SerializerMethodField()
    company_name = serializers.SerializerMethodField()
    update_time = serializers.DateTimeField(format=settings.API_DATETIME_FORMAT)

    def get_company_name(self, instance):
        return instance.company.name

    def get_pay_time(self, instance):
        if instance.supply_order.pay_time:
            return instance.supply_order.pay_time.strftime("%Y-%m-%d %H:%M:%S")
        else:
            return ""

    def get_receiverplace(self, instance):
        receipt_place = ReceiverPlaceSerializers(instance.supply_order.receipt_place, many=False)
        return receipt_place.data

    # def get_goods(self, instance):
    #     goods_name_list = []
    #     orders = instance.child_order.all()
    #     for i in orders:
    #         d = {"num": i.num, "goods": i.goods.goodsname, "cost": i.cost / 100.0}
    #         goods_name_list.append(d)
    #     return goods_name_list

    def get_goods(self, instance):
        goods_name_list = []
        orders = instance.child_order.all()
        for i in orders:
            kwargs = {"many": False, "context": self.context}
            if i.goods.attribute.exists():
                goods_price = GoodsPriceOrderSerializers(i.goods_price, **kwargs).data
                goods_attr = goods_price.get("price_attr_value_set")[0].get("value")
                d = {"num": i.num, "goods": "%s，[%s]" % (i.goods.goodsname, goods_attr), "cost": i.cost / 100.0}
            else:
                d = {"num": i.num, "goods": "%s" % i.goods.goodsname, "cost": i.cost / 100.0}
            goods_name_list.append(d)
        return goods_name_list

    def get_total_cost(self, instance):
        cost = 0
        orders = instance.child_order.all()
        for i in orders:
            cost += i.cost * i.num
        return cost / 100.0

    class Meta:
        model = WomaiOrder
        fields = ("tid", "order_status", "id", "goods", "logistics", "receiverplace",
                  "total_cost", "pay_time", "update_time", "company_name")


class PostRecordSerializers(serializers.ModelSerializer):
    create_time = serializers.DateTimeField(format=settings.API_DATETIME_FORMAT)

    class Meta:
        model = PostRecord
        fields = ("remark", "create_time",)


# 商品属性
class GoodsAttributeSerializers(serializers.ModelSerializer):
    # attr_value_set = GoodsAttributeValueSerializers(many=True)

    attr_value_set = serializers.SerializerMethodField()

    def get_attr_value_set(self, instance):
        kwargs = {"many": True, "context": self.context}
        queryset = instance.attr_value_set.filter(price__goods_id=self.root.instance.id)
        return GoodsAttributeValueSerializers(queryset, **kwargs).data

    class Meta:
        model = GoodsAttribute
        fields = "__all__"


# 商品详情
class GoodsDetailsSerializers(GoodsSerializers):
    company = CompanySerializers(many=False)
    goods_images_details = serializers.SerializerMethodField(label="商品图片", help_text="商品图片")
    goods_images_index = serializers.SerializerMethodField(label="主图", help_text="主图")
    will_sales = serializers.SerializerMethodField(label="预售", help_text="预售")
    active_start_time = ActiveTimeSerializers(label="活动开始时间", help_text="活动开始时间", many=False)

    attribute = GoodsAttributeSerializers(many=True)
    goods_price_set = serializers.SerializerMethodField()

    # goods_price_set = GoodsPriceSerializers()

    def get_goods_price_set(self, obj):
        if obj.goods_price_set:
            kwargs = {"many": True, "context": self.context}
            return GoodsPriceSerializers(obj.goods_price_set.all(), **kwargs).data

    def get_goods_images_details(self, obj):
        # return GoodsImageSerializers(obj.goods_images.all(), many=True, label="详情页的图")
        queryset = obj.goods_images.all()
        serializer = GoodsImageSerializers(queryset, many=True).data
        if obj.prodescription:
            for i in re_goods_detail_wm(obj.prodescription):
                data = OrderedDict([
                    ('path', i),
                    ('type', 2),
                ])
                serializer.append(data)
        return serializer

    def get_goods_images_index(self, obj):
        # return GoodsImageSerializers(obj.goods_images.all(), many=True, label="详情页的图")
        index_image = obj.goods_images.filter(type=4).first()
        return index_image.path

    # 是否是预售
    def get_will_sales(self, obj):
        now_time = datetime.datetime.now()
        if obj.active_start_time and obj.active_start_time.start_time > now_time:
            return False
        else:
            return True

    class Meta:
        model = Goods
        exclude = ('cost', "create_time")


# 购物车商品信息
class CartShopSerializers(BaseGoodsSerializers, BaseGoodsPriceSerializers, GoodsBuyPriceSerializers):
    class Meta:
        model = Goods
        fields = ("goodsname", "will_sales", "goods_images_index", "sales_price_isvip", "sales_price", "price")


# 购物车列表
class CartListSerializers(serializers.ModelSerializer):
    goods_attr_value = serializers.SerializerMethodField()  # 属性值
    goods = CartShopSerializers(read_only=True)
    price_attr_value_set = serializers.SerializerMethodField()  # 商品价格

    def get_goods_attr_value(self, instance):
        if hasattr(instance, "goods_attr_value"):
            kwargs = {"many": True, "context": self.context}
            return GoodsAttributeValueSerializers(instance.goods_attr_value.all(), **kwargs).data
        else:
            return {}

    def get_price_attr_value_set(self, instance):
        if hasattr(instance, "goods_attr_value") and instance.goods_attr_value.first():
            kwargs = {"many": False, "context": self.context}
            return BaseAttrGoodsPriceSerializers(instance.goods_attr_value.first().price, **kwargs).data
        else:
            return {}

    class Meta:
        model = CartItem
        fields = ("goods", "user", "num", "id", "goods_attr_value", "price_attr_value_set")


# 提现
class TransferSerializers(serializers.Serializer):
    transfer_type = serializers.CharField(write_only=True, label="提现类型")
